package com.adxon.data;

import com.adxon.MsgException;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.CompositeFilterOperator;
import com.google.appengine.api.datastore.Query.Filter;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Query.FilterPredicate;
import com.google.appengine.api.datastore.Query.SortDirection;

import java.util.Iterator;

public class DataSet<T> implements Iterable<T>,Iterator<T>{
	protected String			bsk;
	protected Class<?>			cls;
	private Filter				flt;
	protected Iterator<Entity>	itr;
	protected T					nxt;
	protected T					tmp;

	public DataSet(T template){
		flt=new FilterPredicate("tc",FilterOperator.NOT_EQUAL,0);
		prepFilter(template);
		Query q=new Query(bsk);
		q.setFilter(flt);
		q.addSort("tc",SortDirection.DESCENDING);
		itr=DatastoreServiceFactory.getDatastoreService().prepare(q).
				asIterable().iterator();
	}
	protected void addFilter(String name,int value){
		if(value!=0)
			flt=CompositeFilterOperator.and(flt,
					new FilterPredicate(name,FilterOperator.EQUAL,value));
	}
	protected void addFilter(String name,long value){
		if(value!=0)
			flt=CompositeFilterOperator.and(flt,
					new FilterPredicate(name,FilterOperator.EQUAL,value));
	}
	protected void addFilter(String name, String value) {
		if(value!=null)
			flt=CompositeFilterOperator.and(flt,
					new FilterPredicate(name,FilterOperator.EQUAL,value));
	}
	public T getTemplate(){
		return tmp;
	}
	@SuppressWarnings("unchecked")
	@Override
	public boolean hasNext(){
		//System.out.println("hasNext: "+nxt);
		if(nxt==null){
			try{
				while(itr.hasNext()){
					nxt=(T)((Data)cls.newInstance()).update(itr.next());
					if(skip())
						continue;
					return true;
				}
				nxt=null;
			}catch(MsgException e){
			}catch(IllegalAccessException e){
			}catch(InstantiationException e){}
		}else return true;
		return false;
	}
	@Override
	public Iterator<T> iterator(){
		return this;
	}
	@Override
	public T next(){
		T r=nxt;
		nxt=null;
		return r;
	}
	protected void prepFilter(T template){
		bsk=((Base)template).bsk;
		cls=template.getClass();
		tmp=template;
	}
	@Override
	public void remove(){
	}
	protected boolean skip(){
		return false;
	}
}